package com.zf.http_interface.caller.http_interface;


import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.support.RestClientAdapter;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

/**
 * <pre>
 * OpenFeign 依然可以使用，但是同时 Spring 6.0 也提供了另一种替代方案（Http Interface），允许将 “HTTP服务” 定义为 “Java接口”，来代替 Openfeign，具体步骤如下：
 *      1、定义为 Java 接口。
 *      2、在接口中的方法上添加 { HttpExchange、PostExchange、GetExchange ...} 等注解。
 *      3、将接口传递给 HttpServiceProxyFactory 来创建代理对象（内部使用“RestTemplate、RestClient、WebClient”作为HTTP客户端），然后就可以通过代理对象调用服务了。
 *      4、使用 HttpServiceProxyFactory 创建的代理对象，发送"multipart/form-data"类型的请求表单中的文件类型可以是 {@link MultipartFile} 或 {@link Resource} 接口的子类
 *          原因参见：
 *                  {@link HttpServiceProxyFactory.Builder#build()}
 *                  {@link HttpServiceProxyFactory.Builder#initArgumentResolvers()}
 *                  {@link org.springframework.web.service.invoker.RequestPartArgumentResolver}
 *
 * 官方文档：https://docs.spring.io/spring-framework/reference/6.2.5/integration/rest-clients.html#rest-http-interface
 * <pre/>
 */
@Configuration
public class HttpInterfaceInstancesConfig {

    /**
     * 创建 Http Interface 接口的代理对象，注入的spring容器中
     *
     * @param restTemplateBuilder     创建 RestTemplate 用的Builder,
     * @param restClientBuilder       创建 RestClient 用的Builder,
     * @param loadBalancerInterceptor 负载均衡拦截器，拦截url中的服务名并替换成具体的地址（通过负载均衡获得地址），
     *                                一旦添加了该拦截器，就只能使用“服务名”调用服务了
     */
    @Bean("baseHttpInterfaceService")
    public BaseHttpInterfaceService baseHttpInterfaceService(RestTemplateBuilder restTemplateBuilder,
                                                             RestClient.Builder restClientBuilder,
                                                             LoadBalancerInterceptor loadBalancerInterceptor) {
        // 1、使用 RestClient
        // // 添加负载均衡拦截器，添加成功后，可以将下面的url改成服务名：“http://http-interface-target/”
        // restClientBuilder.requestInterceptor(loadBalancerInterceptor);

        // 构建RestClient，设置基本路径
        RestClient restClient = restClientBuilder
                .baseUrl("http://localhost:8118/")
                .build();
        RestClientAdapter adapter = RestClientAdapter.create(restClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory
                .builderFor(adapter)
                // .customArgumentResolver(new HttpServiceArgumentResolver()) // 添加自定义参数解析器，必须是 HttpServiceArgumentResolver 的子类
                .build();
        BaseHttpInterfaceService service = factory.createClient(BaseHttpInterfaceService.class);
        return service;

        // // 2、使用 WebClient，详见官方文档


        // 3、使用 RestTemplate
        // // 添加负载均衡拦截器，添加成功后，可以将下面的url改成服务名：“http://http-interface-target/”
        // restTemplateBuilder = restTemplateBuilder.additionalInterceptors(loadBalancerInterceptor);

        // // 构建 RestTemplate
        // RestTemplate restTemplate = restTemplateBuilder.build();
        // // 设置基本路径
        // restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory("http://localhost:8080/"));
        // RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
        // HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        // CurServerHttpService service = factory.createClient(CurServerHttpService.class);
        // return service;

    }

}
